<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
   
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        html,
        body {
            background: #000;
            margin: 0;
            width: 100%;
            height: 100%;
        }

        canvas {
            width: 100%;
            height: 100%;
            cursor: crosshair;
        }
    </style>

</head>

<body>
    <canvas></canvas>
    <script>
        //1canvas大小自适应
        const canvas = {
            init() {
                //
                this.ele = document.querySelector('canvas')
                //调整画布大小
                this.resize()
                //监听窗体，大小进行调整
                window.addEventListener('resize', () => this.resize(), false)
                return this.ele.getContext('2d');
            },
            resize() {
                //offsetwidth 水平方向的width +panding+border
                this.width = this.ele.width = this.ele.offsetWidth
                this.height = this.ele.height = this.ele.offsetHeight
            }
        }
        const pointer = {
            x: 0,
            y: 0,
            xb: 0,
            yb: 0,
            next: null,//下一次
            frame: 0,//移动次数
            //定义一个鼠标初始化
            init(canvas) {
                //
               canvas.ele.addEventListener('mousemove', e => this.move(e))
            },
            move(e) {
                this.x = e.clientX
                this.y = e.clientY
                //鼠标移动为了开花
                this.shoot(this.x, this.y)
            },
            shoot(x, y) {
                if (!this.next) {
                    //是否第一次进入页面
                    this.next = new Flowers()
                    Flowerse.push(this.next)
                }
                //鼠标移动
                //Math.atan2(y,x)==弧度 返回从（x，y）之间角度
                this.next.shoot(x, y, Math.atan2(y - this.yb, x - this.xb))
                this.next = null
                this.xb = x
                this.xy = y

                this.frame ++
                if( !(this.frame % 3) ){
                    ctx.fillStyle = 'rgba(8,8,8,0.05)'
                    ctx.fillRect(0,0,canvas.width,canvas.height)
                }

            }
        }
        class Flowers {
            constructor() {
                this.x = 0
                this.y = 0
                this.radius = 0
                this.direction = 0//方位
                this.dDir = 0
                this.rightOrLeft = false//花朵旋转方向
                this.shooted = false//开花发芽
                this.color = 0
            }
            //开花往那个方位
           shoot(x, y, direction) {
                this.shooted = true
                this.x = x
                this.y = y
                this.direction = direction
                this.dDir = Math.random()
                this.radius = Math.random() * 20 + 5
                this.rightOrLeft = Math.random() < 0.5
                //颜色的随机
                this.color = `hsl(${Math.floor(Math.random() * 90) - (Math.random() > 0.33 ? 30 : 160)},80%,60%)`
            }
          anim() {
                if (!this.shooted) {
                    pointer.next = this
                    return
                }
                //花朵 坐标 不断发生变化的
                this.x += this.radius * Math.cos(this.direction)
                this.y += this.radius * Math.sin(this.direction)
                ctx.beginPath()
                ctx.fillStyle = this.color
                ctx.arc(this.x, this.y, this.radius * 0.5, 0, 2 * Math.PI)
                ctx.fill()
                ctx.stroke()

                //直线变弧线
                if (this.rightOrLeft) this.direction -= this.dDir;
                else this.direction += this.dDir
                this.radius -= 0.4
                if (this.radius <= 0) this.shooted = false
            }
        }
        // 2画笔
        const ctx = canvas.init()
        //3.鼠标
        //具体操作在画布
        pointer.init(canvas)
        //4.花
        const Flowerse = []
        const play = () => {
            for (const f of Flowerse) {
                //实现一个开花动画效果
                f.anim()
            }
            //执行一个动画 要求浏览器再次重绘之前调用指定的函数 进行动画更新
            requestAnimationFrame(play)
        }
        //初始化效果
        for (let size = 0; size < 2 * Math.PI; size += 0.1) {
            pointer.shoot(
                canvas.width*0.5 + Math.cos(size)*canvas.width*0.25,
                canvas.height*0.5 + Math.sin(size)*canvas.height*0.25
            )
        }
        play()
    </script>
</body>

</html>